/**
 * @description 模拟bind的实现
 */

function isObject(context) {
  typeof context === 'object' && context !== null;
}

function isFunction(context) {
  return typeof context === 'function'
}

Function.prototype._bind = function (_context) {
  if (typeof this !== 'function') {
    throw new TypeError(`${this} must be a function`);
  }
  var _self = this;
  //* 取需要的参数，并转成数组
  var _args = Array.prototype.slice.call(arguments, 1)
  var _binds = function () {
    var _bindsArgs = Array.prototype.slice.call(arguments)
    //* 处理最终要使用到的参数
    var _useArgs = _args.concat(_bindsArgs);
    //* new的时候会走到这里，new.target可解决这个问题
    if (this instanceof _binds) {
      //* 处理原型链，箭头可以直接跳过
      if (_self.prototype) {
        //* 使用了es6的写法，对于es5的写法如下
        //* function emptyFunc(){}
        //* emptyFunc.prototype = _self.prototype
        //* _binds.prototype = new emptyFunc()
        _binds.prototype = Object.create(_self.prototype);
      }
      //* 绑定this
      var res = _self.apply(this, _useArgs)
      //* 非Object大类直接返回
      if (isObject(res) || isFunction(res)) return res
      return this;
    } else return _self.apply(_context, _useArgs)
  }
  return _binds;
}



var foo = {
  text: 1
};
function bar() {
  console.log(this.text);
}
// function bar2() {
//   return () => console.log(this.text)
// }
const bar2 = () => {
  console.log(this.text)
}
var bindfoo = bar._bind(foo);
var bindfoo2 = bar2._bind(foo)
bindfoo();
bindfoo2();